{ "cells": [ { "cell_type": "markdown", "source": [ "# Iterable Variables\n", "\n", "## Try me\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ffraile/computer_science_tutorials/blob/main/source/Introduction/tutorials/Iterable%20Objects%20I.ipynb)[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/ffraile/computer_science_tutorials/main?labpath=source%2FIntroduction%2Ftutorials%2FIterable%20Objects%20I.ipynb)\n", "\n", "## Introduction\n", "If we say that iterable variable are objects that can be iterated over, you will probably ask, *what does iterate over mean?*. In a nutshell, iterating over a variable means that the variable contains a collection of items, and that we will be able to use the variable to easily repeat the same process on each item in the collection. The process of repeating a process over a collection of values is called iteration. For example, if we have a list of numbers, we can iterate over the list and print each number. We will learn more about iterating in the next section on control structures, but for now, we can think of iterable variables as collection of items. The main types of iterable objects are **lists**, **tuples**, and **dictionaries**, but guess what type of primitive variable type is also an iterable variable? You are right! strings are collections of characters! Let us provide an introduction to lists first, which are the most basic type of iterable, and later see how to use lists methods and properties with strings. Finally, we will cover tuples and dictionaries, and provide you some extra cool tips.\n", "\n", "## Lists\n", "**Lists** are the most basic type of array variables. They are just a collection of items, not necessarily of the same type. To create a list, we use the ```[]``` notation. This will create an empty list, with no items or members in the list. We can use the built-in method ```append()``` to append a new member to the list, the built-in method ```pop()``` to remove a member from the list, and the built-in function ```len()``` to get the length of the list:\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "# Create empty list with square brackets\n", "mylist = []\n", "print(\"the length of the mylist is \", len(mylist))\n", "mylist.append(34)\n", "print(\"the length of the mylist is \", len(mylist))\n", "\n", "mylist.append(\"hello\")\n", "print(\"the length of the mylist is \", len(mylist))\n", "\n", "mylist.append(5.0)\n", "print(\"the length of the mylist is \", len(mylist))\n", "\n", "mylist.pop()\n", "print(\"the length of the mylist is \", len(mylist))\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Lists can also be initialised with a collection of values, just providing a comma separated list of values between the brackets." ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "mysecondlist = [1, \"Hello\", 2]\n", "print(\"the length of mysecondlist is\", len(mysecondlist))" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Note that they can contain any type of variable, and they can contain as many variables as you wish. Regardless of the initialization, the list is always mutable and can be modified:\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "mysecondlist.append(\"Oranges\")" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Indexing\n", "We can select a member of a list by appending to its name its **index** between brackets. The index is an integer number used as a key to reference each member of the lists. Indices go from 0, to access the left most element and increase 1 by 1 to access consecutive members from left to right until reaching the length of the list -1 (the right most element). For example, if we want to access the first member of ```mylist```, we can write ```mylist[0]```, and ```mylist[1]``` to get the second member:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "print(mylist[0]) # prints first element\n", "print(mylist[1]) # prints second element\n", "print(mylist[2]) # prints third element" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Ooopsie, we have gone too far! since we popped one element of our list, the length of the list is now 2, and therefore Python raised an 'IndexError: index out of range error' when we tried to access the third element. Beware of this indexing errors when dealing with lists.\n", "\n", "Indices also work in reverse order, from right to left, using negative values. So if we want to access the last element of the list, we can write ```mylist[-1]```, instead of ```mylist[len(mylist)-1]```. Thus, we can traverse the list from right to left using decreasing negative values, ```mylist[-2]``` to get the second last element, and so forth:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "print(mylist[-1]) # prints last element\n", "print(mylist[-2]) # prints second last element" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "One more tip, you can pass the index of the element you want to remove from the list as an argument to the ```pop()``` method. For example, if we want to remove the first element of the list, we can write ```mylist.pop(0)```:\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "mylist.append(\"again\")\n", "mylist.pop(0)\n", "print(mylist)" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Also, the members of a list can be modified:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "\n", "fruit_list = [\"Red\", \"Green\", \"Blue\"]\n", "print(fruit_list)\n", "\n", "fruit_list[1] = \"Orange\"\n", "print(fruit_list)\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "One more tip, you can pass the index of the element you want to remove from the list as an argument to the ```pop()``` method. For example, if we want to remove the first element of the list, we can write ```mylist.pop(0)```:\n" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 8, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['hello', 'again']\n" ] } ], "source": [ "mylist.append(\"again\")\n", "mylist.pop(0)\n", "print(mylist)" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Also, the members of a list can be modified:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 3, "source": [ "\n", "fruit_list = [\"Red\", \"Green\", \"Blue\"]\n", "print(fruit_list)\n", "\n", "fruit_list[1] = \"Orange\"\n", "print(fruit_list)\n" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Red', 'Green', 'Blue']\n", "['Red', 'Orange', 'Blue']\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Arithmetic operators with lists\n", "Python allows to use some basic arithmetic operators with Lists. For instance, we can use the addition operator ```+``` to join/concatenate lists together:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 9, "source": [ "first = [1, 2, 3]\n", "second = [4, 5, 6]\n", "print(first + second)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5, 6]\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "We can use the multiplication ```*``` operator with an integer operand to replicate lists as many times as the operand. For instance, if we want to replicate the list ```first``` three times, we can write ```first * 3```:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 10, "source": [ "\n", "print(first * 3)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 1, 2, 3, 1, 2, 3]\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Indexing and slicing\n", "\n", "We already showed that it is possible ot access individual members of a list with indices, by specifying the index of the member between brackets. Note that if the index is greater or equal than zero, it tells us the position of the member from the left of the array, and if the index is negative, it indicates the position from the end of the array.\n", "\n", "Slicing is used to fetch a given number of subsequent (e.g. consecutive) members of a list.\n", "\n", "The basic slicing syntax is [a:b] where b > a, it will return the members from a to b-1 from left to right:\n" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 12, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "[1, 2]\n", "[4, 5]\n" ] } ], "source": [ "my_list = [1, 2, 3, 4, 5, 6]\n", "print(my_list[0]) # non-negative index: from the beginning of list\n", "print(my_list[0:2]) #Slicing the two first members\n", "print(my_list[-3:-1]) #slicing from the end of the list" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "We can add a third parameter c to control the slice sequence [a:b:c] will return the members from a to b-1 in c steps:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 19, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 3]\n", "[1, 3, 5]\n" ] } ], "source": [ "print(my_list[0:4:2]) #Slicing the first two members and jumping by 2\n", "print(my_list[0:-1:2]) # remember that the index of the last member is -1" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "If c is negative, we will traverse the list in reverse order, from the end to the beginning:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "print(my_list[3:0:-1]) # slicing in reverse order\n", "print(my_list[::2]) # Slicing odd members (leave empty to use first and last)" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "By default, the first parameter of a slice is 0, and the default parameter of second is -1, and the third is 1, so we can leave any parameter blank to use these default values:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 20, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[6, 5, 4, 3, 2, 1]\n", "[6, 4, 2]\n", "[1, 2]\n" ] } ], "source": [ "print(my_list[::-1]) # slicing all members in reverse order\n", "print(my_list[::-2]) # slicing all members in reverse order and jumping by 2\n", "print(my_list[:2]) # slicing all members from the first two members\n" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "### Logical Operator in\n", "The logical operator ```in``` returns True if an array contains a specific member:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 21, "source": [ "name = \"Paco\"\n", "if name in [\"Paco\", \"Pepe\"]:\n", " print(\"Your name is either Paco or Pepe.\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your name is either Paco or Pepe.\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "## Strings\n", "As mentioned above, string variable are also iterable variables, meaning that we can use indexing:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 6, "source": [ "text = \"Hello world!\"\n", "print(text[1])\n", "print(text[5])" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "e\n", " \n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "And slicing!" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 4, "source": [ "text = \"Hello world!\"\n", "print(text[3:9])" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "lo wor\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "As with lists, if you want to indicate the firts index or the last index, you should use empty indexes:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 10, "source": [ "text = \"Hello world!\"\n", "# Prints from index 5 to the end\n", "print(text[5:])\n", "# Prints from the beginning to index 7 (excluded)\n", "print(text[:7])\n", "# Prints from the beginning to the end, which is the same as print(text)\n", "print(text[:])" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ " world!\n", "Hello w\n", "Hello world!\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "Can you use indexing to print a text in reverse order? Yes you can!" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 6, "source": [ "text = \"Hello world!\"\n", "print(text[::-1])" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "!dlrow olleH\n" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } }, { "cell_type": "markdown", "source": [ "So, by all means strings are iterable objects and therefore we can select individual characters as members, but recall that, just as any other built-in type, strings are **immutable** objects and therefore their members cannot be modified:" ], "metadata": { "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 1, "source": [ "text = \"Hello world!\"\n", "print(text[0])\n", "text[0] = \"h\" #this will not work" ], "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "H\n" ] }, { "output_type": "error", "ename": "TypeError", "evalue": "'str' object does not support item assignment", "traceback": [ "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m", "\u001B[1;31mTypeError\u001B[0m Traceback (most recent call last)", "\u001B[1;32m\u001B[0m in \u001B[0;36m\u001B[1;34m\u001B[0m\n\u001B[0;32m 1\u001B[0m \u001B[0mtext\u001B[0m \u001B[1;33m=\u001B[0m \u001B[1;34m\"Hello world!\"\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0;32m 2\u001B[0m \u001B[0mprint\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mtext\u001B[0m\u001B[1;33m[\u001B[0m\u001B[1;36m0\u001B[0m\u001B[1;33m]\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m----> 3\u001B[1;33m \u001B[0mtext\u001B[0m\u001B[1;33m[\u001B[0m\u001B[1;36m0\u001B[0m\u001B[1;33m]\u001B[0m \u001B[1;33m=\u001B[0m \u001B[1;34m\"h\"\u001B[0m \u001B[1;31m#this will not work\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m", "\u001B[1;31mTypeError\u001B[0m: 'str' object does not support item assignment" ] } ], "metadata": { "pycharm": { "name": "#%%\n" } } } ], "metadata": { "kernelspec": { "name": "python3", "display_name": "Python 3.8.1 64-bit" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.1" }, "interpreter": { "hash": "2db524e06e9f5f4ffedc911c917cb75e12dbc923643829bf417064a77eb14d37" } }, "nbformat": 4, "nbformat_minor": 4 }